﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using DiscoveryLogic.Analytics.DataObjects;
using DiscoveryLogic.Analytics.DataObjects.Networks;
using DiscoveryLogic.Common.Utilities;

namespace DiscoveryLogic.Analytics.BusinessLogic.Networks
{
    public class NetworkManager
    {
        public static List<NetworkDefinition> GetNetworkDefs(SetDataSourceType srcType, string iconPath)
        {
            List<NetworkDefinition> networkDefs=new List<NetworkDefinition>();
            string appFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            appFolderPath = Path.Combine(appFolderPath, "Network Data");
            if (!Directory.Exists(appFolderPath))
                Directory.CreateDirectory(appFolderPath);
            string netDefFilePath = Path.Combine(appFolderPath, "NetworkDefinition.xml");
            if(File.Exists(netDefFilePath))
            {
                XmlDocument xDoc = new XmlDocument();
                xDoc.Load(netDefFilePath);
                XmlNode root = xDoc.DocumentElement;
                XmlNodeList netDefNodes = root.SelectNodes("NetworkDef");
                if(netDefNodes !=null && netDefNodes.Count>0)
                {
                    foreach (XmlNode netDefNode in netDefNodes)
                    {
                        SetDataSourceType srcType2 =
                            (SetDataSourceType)
                            Enum.Parse(typeof (SetDataSourceType),
                                       XmlDataUtil.GetAttributeValue(netDefNode, "SrcType",
                                                                     SetDataSourceType.DB.ToString()));
                        if (srcType2 == srcType)
                        {
                            NetworkDefinition networkDef = NetworkDefinition.Read(netDefNode);
                            networkDefs.Add(networkDef);
                        }
                    }
                }
                
            }
            
            return networkDefs;
        }

        public static void Save(NetworkDefinition netDef)
        {
            string appFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            appFolderPath = Path.Combine(appFolderPath, "Network Data");
            if (!Directory.Exists(appFolderPath))
                Directory.CreateDirectory(appFolderPath);
            string netDefFilePath = Path.Combine(appFolderPath, "NetworkDefinition.xml");
            XmlDocument xDoc=new XmlDocument();
            XmlNode netDefNode = null;
            if (File.Exists(netDefFilePath))
            {
                xDoc.Load(netDefFilePath);
                netDefNode =
                    xDoc.DocumentElement.SelectSingleNode("NetworkDef[@NetworkName=\"" + netDef.NetworkName + "\"]");
                if(netDefNode==null)
                {
                    XmlNode root = xDoc.DocumentElement;
                    netDefNode = XmlDataUtil.AddElement(ref xDoc, root, "NetworkDef");
                }
                else
                {
                    netDefNode.RemoveAll();
                }
            }
            else
            {
                xDoc.LoadXml("<NetworkDefs></NetworkDefs>");
                XmlNode root = xDoc.DocumentElement;
                netDefNode = XmlDataUtil.AddElement(ref xDoc, root, "NetworkDef");
            }
            netDef.Save(ref xDoc, netDefNode);
            xDoc.Save(netDefFilePath);
        }

        public static List<string> GetAllNetworkNames()
        {
            string appFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            appFolderPath = Path.Combine(appFolderPath, "Network Data");
            if (!Directory.Exists(appFolderPath))
                Directory.CreateDirectory(appFolderPath);
            DirectoryInfo dirInfo=new DirectoryInfo(appFolderPath);
            FileInfo[] files = dirInfo.GetFiles("*.net", SearchOption.TopDirectoryOnly);
            List<string> networkNames=new List<string>();
            if(files !=null && files.Length>0)
            {
                foreach(FileInfo file in files)
                {
                    if (!file.Name.ToLower().EndsWith(".net"))
                        continue;
                    networkNames.Add(Path.GetFileNameWithoutExtension(file.FullName));
                }
            }
            return networkNames;
        }

        public static List<Network> GetAllNetworks()
        {
            List<Network> networks=new List<Network>();
            string appFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            appFolderPath = Path.Combine(appFolderPath, "Network Data");
            if (!Directory.Exists(appFolderPath))
                Directory.CreateDirectory(appFolderPath);
            DirectoryInfo dirInfo = new DirectoryInfo(appFolderPath);
            FileInfo[] files = dirInfo.GetFiles("*.net", SearchOption.TopDirectoryOnly);
            if (files != null && files.Length > 0)
            {
                foreach (FileInfo file in files)
                {
                    if (!file.Name.ToLower().EndsWith(".net"))
                        continue;
                    Network network = Network.Read(Path.GetFileNameWithoutExtension(file.FullName));
                    networks.Add(network);
                }
            }
            return networks;
        }

        public static List<Network> GetNetworks(EntityType entityType)
        {
            List<Network> networks = new List<Network>();
            string appFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            appFolderPath = Path.Combine(appFolderPath, "Network Data");
            if (!Directory.Exists(appFolderPath))
                Directory.CreateDirectory(appFolderPath);
            DirectoryInfo dirInfo = new DirectoryInfo(appFolderPath);
            FileInfo[] files = dirInfo.GetFiles("*.net", SearchOption.TopDirectoryOnly);
            if (files != null && files.Length > 0)
            {
                foreach (FileInfo file in files)
                {
                    if(!file.Name.ToLower().EndsWith(".net"))
                        continue;
                    Network network = Network.Read(Path.GetFileNameWithoutExtension(file.FullName));
                    bool containsEntityType = false;
                    if(network !=null && network.Records !=null && network.Records.Count>0)
                    {
                        foreach (EntityBase entity in network.Records)
                        {
                            if(entity.EntityType==entityType)
                            {
                                containsEntityType = true;
                                break;
                            }
                        }
                    }
                    if (containsEntityType)
                        networks.Add(network);
                }
            }
            return networks;
        }

        public static void Delete(Network network)
        {
            string networkFilePath = Path.Combine(
                DataFolder.NetworkDataFolder, network.NetworkName + DataFolder.NetworkFileExtension);
            if(File.Exists(networkFilePath))
                File.Delete(networkFilePath);

            string netMeasureFilePath = Path.Combine(
                DataFolder.NetworkDataFolder, network.NetworkName + DataFolder.NetworkMeasureFileExtension);
            if(File.Exists(netMeasureFilePath))
                File.Delete(netMeasureFilePath);

            string netClusterFilePath = Path.Combine(
                DataFolder.NetworkDataFolder, network.NetworkName + DataFolder.NetworkClusterFileExtension);
            if(File.Exists(netClusterFilePath))
                File.Delete(netClusterFilePath);

            string includeSettingFilePath =
                Path.Combine(
                    DataFolder.NetworkDataFolder, network.NetworkName + DataFolder.NetworkInclusionSettingFileExtension);
            if(File.Exists(includeSettingFilePath))
                File.Delete(includeSettingFilePath);

            string exSettingFilePath = Path.Combine(
                DataFolder.NetworkDataFolder, network.NetworkName + DataFolder.NetworkExclusionSettingFileExtension);
            if(File.Exists(exSettingFilePath))
                File.Delete(exSettingFilePath);
        }
    }
}
